from contextlib import asynccontextmanager
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from fastapi.exceptions import RequestValidationError
from starlette.exceptions import HTTPException
import logging
from src.core.config import settings
from src.core.dependencies import (
    init_db_pool,
    init_redis_client,
    close_db_pool,
    close_redis_client
)
from src.core.middleware import (
    ErrorHandlingMiddleware,
    RequestLoggingMiddleware,
    http_exception_handler,
    validation_exception_handler,
    general_exception_handler
)
from src.core.rate_limiter import RateLimitMiddleware
from src.api.v1.endpoints import auth

# Configure logging
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)

logger = logging.getLogger(__name__)


@asynccontextmanager
async def lifespan(app: FastAPI):
    """Application lifespan manager."""
    # Startup
    logger.info("Starting auth service...")
    
    # Initialize database pool
    await init_db_pool()
    logger.info("Database connection pool initialized")
    
    # Initialize Redis client
    await init_redis_client()
    logger.info("Redis client initialized")
    
    yield
    
    # Shutdown
    logger.info("Shutting down auth service...")
    
    # Close database pool
    await close_db_pool()
    logger.info("Database connection pool closed")
    
    # Close Redis client
    await close_redis_client()
    logger.info("Redis client closed")


# Create FastAPI app
app = FastAPI(
    title=settings.APP_NAME,
    version=settings.APP_VERSION,
    lifespan=lifespan
)

# Add CORS middleware
app.add_middleware(
    CORSMiddleware,
    allow_origins=settings.CORS_ORIGINS,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# Add custom middleware
app.add_middleware(ErrorHandlingMiddleware)
app.add_middleware(RequestLoggingMiddleware)
app.add_middleware(RateLimitMiddleware)

# Register exception handlers
app.add_exception_handler(HTTPException, http_exception_handler)
app.add_exception_handler(RequestValidationError, validation_exception_handler)
app.add_exception_handler(Exception, general_exception_handler)

# Include routers
app.include_router(auth.router)


@app.get("/health")
async def health_check():
    """Health check endpoint."""
    return {
        "status": "healthy",
        "service": "auth",
        "version": settings.APP_VERSION
    }


@app.get("/")
async def root():
    """Root endpoint."""
    return {
        "service": settings.APP_NAME,
        "version": settings.APP_VERSION,
        "status": "running"
    }


if __name__ == "__main__":
    import uvicorn
    uvicorn.run(
        "main:app",
        host="0.0.0.0",
        port=8000,
        reload=settings.DEBUG,
        log_level="info"
    )